package com.icez.base_util_library

import android.net.Uri
import org.java_websocket.WebSocket
import org.java_websocket.client.WebSocketClient
import org.java_websocket.enums.ReadyState
import org.java_websocket.handshake.ServerHandshake
import java.lang.Exception
import java.net.URI
import javax.net.ssl.SSLParameters

/**
 *  websocket 工具类
 * 测试地址：ws://121.40.165.18:8800
 * 参考网页：http://www.websocket-test.com/
 */
class WebSocketUtil {
    companion object {
        val CURRENTTAGNAME = WebSocketUtil.javaClass.simpleName
        val instance: WebSocketUtil by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            WebSocketUtil()
        }
        var mWebSocketClient: JavaWebSocketClient? = null
    }

    /**
     *  初始化配置
     * @param serverUri websocket 地址 ws:// ip地址 : 端口号
     * @param mWebSocketClient websocket 回调
     */
    public suspend fun initConnectConfig(serverUri: String, mOnWebSocketListener: OnWebSocketListener?) {
        try {
            if (mWebSocketClient != null) {
                return
            }
            val uri = URI.create(serverUri)
            mWebSocketClient = JavaWebSocketClient(uri, mOnWebSocketListener)
            LogUtil.E("初始化成功")
        } catch (e: Exception) {
            LogUtil.E(CURRENTTAGNAME+" initConnectConfig error: "+e.message)
        }
    }

    /**
     *  开始连接
     */
    public suspend fun startConnect() {
        try{
            if (mWebSocketClient == null) {
                return
            }
            if(mWebSocketClient?.isOpen==false){
                if(mWebSocketClient?.readyState==ReadyState.NOT_YET_CONNECTED){
                    mWebSocketClient?.connectBlocking()
                }else if(mWebSocketClient?.readyState==ReadyState.CLOSED||mWebSocketClient?.readyState==ReadyState.CLOSING){
                    mWebSocketClient?.reconnectBlocking()
                }

            }

        }catch (e: Exception){
            LogUtil.E(CURRENTTAGNAME+" startConnect error: "+e.message)
        }
    }

    /**
     *  关闭连接
     *
     */
    public suspend fun closeConnect(){
        try{
            if (mWebSocketClient == null) {
                return
            }
            if(mWebSocketClient?.isOpen==true){
                mWebSocketClient?.closeBlocking()
                mWebSocketClient = null
            }

        }catch (e: Exception){
            LogUtil.E(CURRENTTAGNAME+" closeConnect error: "+e.message)
        }
    }

    /**
     *  发送消息
     * @param message 消息内容
     */
    public suspend fun sendMessage(message:String){
        try{
            if (mWebSocketClient == null) {
                return
            }
            if(mWebSocketClient?.isOpen==true){
                mWebSocketClient?.send(message)
            }

        }catch (e: Exception){
            LogUtil.E(CURRENTTAGNAME+" sendMessage error: "+e.message)
        }
    }


    /**
     *  websocket 回调
     */
    interface OnWebSocketListener {
        /**
         *  开始连接
         */
        fun onStartConnect()

        /**
         *  消息监听
         * @param message 消息
         */
        fun onMessage(message: String?)

        /**
         *  关闭连接
         * @param reason 关闭原因
         */
        fun onCloseConnect(reason:String?)

        /**
         *  websocket 发生错误
         */
        fun onError(ex: Exception?)
    }

    /**
     *  java - websocket
     * @param serverUri 服务器地址
     * @param mOnWebSocketListener 回调
     */
    class JavaWebSocketClient(serverUri: URI?, val mOnWebSocketListener: OnWebSocketListener?) :
        WebSocketClient(serverUri) {
        override fun onOpen(handshakedata: ServerHandshake?) {
            mOnWebSocketListener?.onStartConnect()
        }

        override fun onMessage(message: String?) {
            mOnWebSocketListener?.onMessage(message)
        }

        override fun onClose(code: Int, reason: String?, remote: Boolean) {
            mOnWebSocketListener?.onCloseConnect(reason)
        }

        override fun onError(ex: Exception?) {
            mOnWebSocketListener?.onError(ex)
        }
        override fun onSetSSLParameters(sslParameters: SSLParameters?) {
            if (android.os.Build.VERSION.SDK_INT > 23) {
                super.onSetSSLParameters(sslParameters)
            } else {
                LogUtil.E("Fix No such method error setEndpointIdentificationAlgorithm on pre android 24.")
            }
        }
    }


}